<?php

class S_Cart {

	//购物车条目
	private $items = array();
	
	//最大数量限制
	private $max_quantity = 50;
	
	//购物车最大记录
	private $max_row = 50;
	
	//生命周期
	private $lifetime = 604800;
	
	//错误信息
	private $error;

	public function __construct($config = array())
	{
		$defaults = array(
			'max_quantity',
			'max_row',
			'lifetime'
		);
		
		if ($config && is_array($config))
		{
			foreach ($defaults as $key)
			{
				if (isset($config[$key]))
				{
					$this->$key = intval($config[$key]) ? intval($config[$key]) : $this->$key;
				}
			}	
		}
		$this->init();
	}
	
	//加入购物车
	public function insert($item)
	{
		if ( ! is_array($item) || ! $item)
		{
			$this->set_error('记录必须是个非空数组');
			return FALSE;
		}
		
		//商品id，商品名称，商品价格必须设置
		if ( ! isset($item['id']) || ! isset($item['name']) || ! isset($item['price']))
		{
			$this->set_error('商品ID，商品名称，商品价格必须设置');
			return FALSE;
		}
		
		//商品id必须是字符串或数值
		if (( ! is_string($item['id']) || ! is_numeric($item['id'])) && trim($item['id'])=='')
		{
			$this->set_error('商品ID必须是个非空字符串或数值');
			return FALSE;
		}
		else
		{
			$item['id'] = trim($item['id']);
		}
		
		//商品名称必须为字符串
		if ( ! is_string($item['name']) || trim($item['name'])=='')
		{
			$this->set_error('商品名称必须是个非空字符串');
			return FALSE;
		}
		else
		{
			$item['name'] = trim($item['name']);
		}
		
		//商品价格必须为数值
		if ( ! is_numeric($item['price']))
		{
			$this->set_error('商品价格必须是个数值');
			return FALSE;
		}
		else
		{
			$item['price'] = round(floatval($item['price']), 2);
		}
		
		//商品数量如果设置了，必须为整数数值
		if (isset($item['quantity']))
		{
			if ( ! is_numeric($item['quantity']) || intval($item['quantity'])<1)
			{
				$this->set_error('购买商品数量必须是个大于0的整数字符串或数值');
				return FALSE;
			}
			else
			{
				$item['quantity'] = intval($item['quantity'])>$this->max_quantity ? $this->max_quantity : intval($item['quantity']);
			}
		}
		else
		{
			$item['quantity'] = 1;
		}

		//其他选项（options）必须是个值为字符串或数值的一维数组
		if (isset($item['options']))
		{
			if ( ! is_array($item['options']))
			{
				$this->set_error('商品其他信息必须是个数组');
				return FALSE;
			}
			elseif ($item['options'])
			{
				foreach ($item['options'] as &$option)
				{
					if ( ! is_string($option) || ! is_numeric($option))
					{
						$this->set_error('商品其他信息数组内容必须是字符串或数值');
						return FALSE;
					}
					{
						$option = trim($option);
					}
				}
			}
		}
		else
		{
			$item['options'] = array();
		}
		
		$rowid = md5($item['id'].implode('', $item['options']));
		
		//如果存在同样的记录，则添加数量，否则写入
		if (isset($this->items[$rowid]))
		{
			$this->items[$rowid]['quantity'] += $item['quantity'];
			if ($this->items[$rowid]['quantity']>$this->max_quantity)
			{
				$this->items[$rowid]['quantity'] = $this->max_quantity;
			}
		}
		else
		{
			$save_item = array(
				'id' => $item['id'],
				'name' => $item['name'],
				'price' => $item['price'],
				'quantity' => $item['quantity'],
				'options' => $item['options']
			);
			
			//判断是否超过购物车最大记录数
			if (count($this->items)>$this->max_row)
			{
				$this->set_error('购物车已经满了');
				return FALSE;
			}
			
			$this->items[$rowid] = $save_item;
		}
		
		if ( ! $this->save_cart())
		{
			$this->set_error('保存购物车失败');
			return FALSE;
		}
		
		return $rowid;
	}
	
	//删除购物车
	public function delete($rowid)
	{
		if (isset($this->items[$rowid]))
		{
			unset($this->items[$rowid]);
			
			if ( ! $this->save_cart())
			{
				$this->set_error('保存购物车失败');
				return FALSE;
			}
			
			return TRUE;
		}
		$this->set_error('购物车记录不存在');
		return FALSE;
	}
	
	//修改购物车
	public function update($rowid, $quantity)
	{
		if ( ! is_string($rowid) || strlen($rowid)!=32)
		{
			$this->set_error('购车车记录ID必须是个32位字符串');
			return FALSE;
		}
		
		$quantity = intval($quantity);
		
		//判断是否大于购物车商品数量限制
		$quantity = $quantity>$this->max_quantity ? $this->max_quantity : $quantity;
		
		if (isset($this->items[$rowid]))
		{
			//如果数量等于0，从购物车中删除这条记录
			if ($quantity==0)
			{
				return $this->delete($rowid);
			}
			
			//修改的数量跟记录一样，直接返回false
			if ($this->items[$rowid]['quantity']==$quantity)
			{
				return TRUE;
			}
			
			$this->items[$rowid]['quantity'] = $quantity;
			if ( ! $this->save_cart())
			{
				$this->set_error('保存购物车失败');
				return FALSE;
			}
		}
		
		$this->set_error('购物车记录不存在');
		return FALSE;
	}
	
	//返回购物车内容，数组列表
	public function contents()
	{
		return $this->items;
	}
	
	//返回总金额
	public function total()
	{
		$total = 0;
		if ($this->items)
		{
			foreach ($this->items as $item)
			{
				$total += $item['price']*$item['quantity'];
			}
		}
		return $total;
	}
	
	//销毁购物车
	public function destroy()
	{
		$this->items = array();
		if ( ! $this->save_cart())
		{
			$this->set_error('保存购物车失败');
			return FALSE;
		}
		return TRUE;
	}
	
	//设置错误信息
	protected function set_error($error)
	{
		$this->error = trim($error);
	}
	
	//返回错误信息
	public function get_error()
	{
		return $this->error;
	}
	
	//返回购物车
	protected function init()
	{
		$content = '';
		
		/*
		 * DOIT
		 * $content = isset($_COOKIE['cart_content']) ? $_COOKIE['cart_content'] : '';
		 */
		
		$content = isset($_COOKIE['cart_content']) ? $_COOKIE['cart_content'] : '';
		
		$this->items = unserialize($content);
		$this->items = $this->items ? $this->items : array();
	}
	
	//保存购物车
	protected function save_cart()
	{
		$content = serialize($this->items);

		/*
		 * DOIT
		 * setcookie('cart_content', $content, time()+$this->lifetime);
		 */
		
		setcookie('cart_content', $content, time()+$this->lifetime);

		return TRUE;
	}

}